﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace PKSpeed
{
    /// <summary>
    /// 文件系统相关命令
    /// </summary>
    class FileOperation
    {
        //盘符
        private static String _driver = "C:";
        // 判断是否为隐藏目录
        public static bool IsHiddenDir(DirectoryInfo di)
        {
            if (di.Attributes.ToString().IndexOf("Hidden") == -1) //如果属性为隐藏
            {
                return false;
            }
            return true;
        }
        // 判断是否为隐藏文件
        public static bool IsHiddenFile(FileInfo fi)
        {
            if (fi.Attributes.ToString().IndexOf("Hidden") == -1) //如果属性为隐藏
            {
                return false;
            }
            return true;
        }
        //得到文件目录的大小
        public static long GetDirectorySize(DirectoryInfo di)
        {
            FileInfo[] files = di.GetFiles();   //得到文件夹所有文件
            DirectoryInfo[] dis = di.GetDirectories(); //得到文件夹所有子文件夹
            return files.Sum(fileInfo => fileInfo.Length) + dis.Sum(directoryInfo => GetDirectorySize(directoryInfo));
        }
        //重定位
        static bool Relocation(List<String> str, String path)
        {
            String value = "";
            if (File.Exists(path))
            {
                while (value != "N" && value != "n" && value != "Y" && value != "y")
                {
                    Console.WriteLine("是否覆盖？Y/N");
                    value = Console.ReadLine();
                    if (value == "N" || value == "n")  //选择否就不覆盖
                        return false;
                    if (value == "Y" || value == "y")  //选择是就覆盖
                    {
                        Write(path, str);  //写入文件
                        return true;
                    }
                }
            }
            else
            {
                Write(path, str);    //写入文件
                return true;
            }
            return false;
        }

        //排序
        static List<String> SortbyDic(List<String> str)
        {
            str = str.OrderBy(s =>
            {
                double res = 0;
                double f = 0.01f;
                foreach (char c in s)
                {
                    res += f * (c - ' ');     //计算出一个字符串的ascall值，根据值排序
                    f *= 0.01f;
                }
                return res;
            }).ToList();
            return str;
        }

        //管道函数
        static List<String> Grep(List<String> grepArg, List<String> map)
        {
            List<String> ret = new List<string>();
            foreach (string s in map)
            {
                int sign = 1;
                for (int i = 0; i < grepArg.Count; i++)
                {
                    if (s.IndexOf(grepArg.ElementAt(i)) == -1)   //如果字符串不存在匹配的关键字，就过滤
                    {
                        sign = 0;
                        break;
                    }

                }
                if (sign == 1)
                    ret.Add(s);    //完全匹配的放入字符串
            }
            return ret;
        }

        //写函数
        public static void Write(String path, List<String> str)
        {
            FileStream fs = new FileStream(path, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            //开始写入
            foreach (string s in str)
            {
                sw.WriteLine(s);
            }
            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();
        }

        //读函数
        public static List<String> Read(String path)
        {
            if (!File.Exists(path))
                return null;
            List<String> list = new List<string>();
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);
            //开始写入
            String c = null;
            c = sr.ReadLine();
            while (c != null)
            {
                list.Add(c);
                c = sr.ReadLine();
            }
            //关闭流
            sr.Close();
            fs.Close();
            return list;
        }
        //判断为目录或者文件
        static int Check(String path)
        {
            if (!File.Exists(path) && !Directory.Exists(path))
                return 0;
            if (File.Exists(path) && !Directory.Exists(path))
                return 1;
            if (!File.Exists(path) && Directory.Exists(path))
                return 2;

            return -1;
        }
        //kind=0时,复制文件到目录,kind=1时，移动文件到目录
        static bool CpfTod(String s, String d, String name, int kind)
        {
            FileInfo fi = new FileInfo(s);
            DirectoryInfo di = new DirectoryInfo(d);
            String path = d + '/' + fi.Name;  //地址path为文件地址
            String tmp = "";
            if (kind == 0)
                tmp = "复制";
            else
                tmp = "移动";
            if (name != null)
                path = d + '/' + name;
            String value = "";
            if (File.Exists(path))    //文件存在
            {
                while (value != "1" && value != "2" && value != "3")
                {
                    if (name == null)
                        Console.WriteLine("文件" + fi.Name + "已经存在");
                    else
                    {
                        Console.WriteLine("文件" + name + "已经存在");
                    }
                    Console.WriteLine("1.替换");
                    Console.WriteLine("2.取消" + tmp);
                    Console.WriteLine("3." + tmp + "但不替换");
                    value = Console.ReadLine();
                    if (value == "2")   //返回
                        return false;
                    if (value == "1")  //直接替换已存在的文件
                    {

                        fi.CopyTo(path, true);
                        return true;
                    }
                    if (value == "3") //创建副本
                    {
                        String str = path;
                        if (name != null)
                            str = name;
                        else
                            str = fi.Name;
                        String str1 = "";
                        String str2 = "";
                        if (str.IndexOf('.') == -1) //如果是没有后缀的文件
                        {
                            str1 = str;
                            str2 = "";
                        }
                        else       //有后缀的文件
                        {
                            str1 = str.Substring(0, str.LastIndexOf('.'));
                            str2 = str.Substring(str.LastIndexOf('.'));
                        }

                        for (int i = 2; ; i++)  //若文件已经存在，就建一个副本
                        {
                            if (!File.Exists(d + "/" + str1 + "(" + i.ToString() + ")" + str2))
                            {
                                fi.CopyTo(d + "/" + str1 + "(" + i.ToString() + ")" + str2, true);
                                break;
                            }
                        }
                    }
                }

            }
            else
            {
                try
                {
                    fi.CopyTo(path);  //复制文件到path
                }
                catch (System.IO.PathTooLongException)
                {
                    Console.WriteLine("文件名过长!");
                    return false;
                }
                catch (System.ArgumentException)
                {
                    Console.WriteLine("文件名非法!");
                    return false;
                }
                return true;
            }
            return true;
        }

        //kind=0时,复制文件到文件,kind=1时，移动文件到文件
        static bool CpfTof(String s, String d, int kind)
        {
            FileInfo fi = new FileInfo(d);
            FileInfo fi1 = new FileInfo(s);
            String dir = fi.Directory.FullName; //dir为fi的目录路径
            CpfTod(fi1.FullName, dir, fi.Name, kind); //将文件复制到目录
            return true;
        }

        //kind=0时,复制目录到目录,kind=1时，移动目录到目录
        static bool CpdTod(String d1, String d2, int kind)
        {
            DirectoryInfo di1 = new DirectoryInfo(d1);
            String[] str = Directory.GetFiles(d1);  //str数组是d1下的文件名
            String[] str1 = Directory.GetDirectories(d1);//str数组是d1下的目录名
            DirectoryInfo di2 = new DirectoryInfo(d2);
            String path = d2 + "/" + di1.Name;
            String tmp = "";
            if (kind == 0)
                tmp = "复制";
            else
                tmp = "移动";
            if (Directory.Exists(path)) //判断目录是否存在
            {
                String value = "";
                while (value != "1" && value != "2")
                {
                    Console.WriteLine("目录" + di1.Name + "已经存在");
                    Console.WriteLine("1.合并目录。");
                    Console.WriteLine("2.取消" + tmp + "。");
                    value = Console.ReadLine();   //得到输入的选项
                    if (value == "2")
                        return false;
                    if (value == "1")
                    {
                        foreach (String s in str)
                        {
                            CpfTod(s, path, null, kind); //将文件复制到目的地址
                        }
                        foreach (String s in str1)
                        {
                            CpdTod(s, path, kind); //将目录复制到目的地址
                        }
                    }

                }
            }
            else
            {
                Directory.CreateDirectory(path);
                foreach (String s in str)
                {
                    CpfTod(s, path, null, kind); //复制到目的地址
                }
                foreach (String s in str1)
                {
                    CpdTod(s, path, kind);
                }
                return true;
            }
            return true;
        }

        //判断是否为文件名
        static bool CheckFile(String s)
        {
            //目录名不能为\ / : * ? ” < > | '; 和空格
            if (s.IndexOf('\\') != -1 || s.IndexOf('/') != -1 || s.IndexOf(' ') != -1 || s.IndexOf(':') != -1 || s.IndexOf('*') != -1 || s.IndexOf('?') != -1 || s.IndexOf('"') != -1 || s.IndexOf('|') != -1 || s.IndexOf('\'') != -1 || s.IndexOf('’') != -1 || s.IndexOf('<') != -1 || s.IndexOf('>') != -1)
            {
                return false;
            }
            else
                return true;
        }

        //删除目录
        static void Delete(String d)
        {
            DirectoryInfo di = new DirectoryInfo(d);
            foreach (FileInfo fi in di.GetFiles())
            {
                fi.Delete();  //删除目录下的每个文件
            }
            foreach (DirectoryInfo di1 in di.GetDirectories())
            {
                Delete(di1.FullName); //删除目录下的每个文件夹
            }
            Directory.Delete(di.FullName);
        }

        //新建文件夹
        static void MakeDir(string absolutePath, int lastIndex)
        {
            DirectoryInfo di = new DirectoryInfo(absolutePath);
            if (CheckFile(di.Name))
                Directory.CreateDirectory(absolutePath);
            else
            {
                Console.WriteLine("文件夹名非法!");
                return;
            }
        }

        //查找文件
        static void FindFile(String path, String file, List<String> tmp, String start)
        {
            DirectoryInfo di = new DirectoryInfo(path);
            foreach (FileInfo fi in di.GetFiles())
            {
                if (!String.IsNullOrEmpty(file) && fi.Name == file && !IsHiddenFile(fi)) //若找到匹配的文件，就放入数组
                {
                    tmp.Add(start + fi.Name);
                }
                else
                    if (String.IsNullOrEmpty(file) && !IsHiddenFile(fi))          //若没有匹配规则，就把所有的文件放入数组
                    {
                        tmp.Add(start + fi.Name);
                    }
            }
            foreach (DirectoryInfo di1 in di.GetDirectories())
            {
                if (file != null && di1.Name == file&&!IsHiddenDir(di1))
                {
                    tmp.Add(start + di1.Name); //若找到匹配的文件夹，就放入数组
                }
                else
                    if (String.IsNullOrEmpty(file) && !IsHiddenDir(di1))
                    {
                        tmp.Add(start + di1.Name);//若没有匹配规则，就把所有的文件夹放入数组
                    }
                FindFile(di1.FullName, file, tmp, start + di1.Name + "/");
            }

        }

        //高亮输出
        public static void Out(String sign, List<String> str)
        {
            ConsoleColor defaultColor = Console.ForegroundColor;
            String tmp = "";
            List<Int32> list = new List<Int32>();
            int index = 0;
            for (int i = 0; i < str.Count; i++)
            {
                list.Clear();
                tmp = str.ElementAt(i);
                index = tmp.IndexOf(sign);
                list.Add(index);
                while (true)
                {
                    if (index + sign.Length < tmp.Length)
                        index = tmp.IndexOf(sign, index + sign.Length);
                    else
                    {
                        break;
                    }
                    if (index == -1)
                        break;
                    list.Add(index);
                }
                for (int j = 0; j < tmp.Length; j++)
                {

                    if (list.IndexOf(j) != -1)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        int k;
                        for (k = j; k < j + sign.Length; k++)
                            Console.Write(tmp.ElementAt(k));
                        j = k - 1;
                    }
                    else
                    {
                        Console.ForegroundColor = defaultColor;
                        Console.Write(tmp.ElementAt(j));
                    }
                }
                Console.ForegroundColor = defaultColor;
                Console.Write("\n");
            }
        }

        public static void Out1(String sign, List<String> str)
        {
            ConsoleColor defaultColor = Console.ForegroundColor;
            String tmp = "";
            List<Int32> list = new List<Int32>();
            int index = 0;
            for (int i = 0; i < str.Count; i++)
            {
                list.Clear();
                tmp = str.ElementAt(i);
                index = tmp.IndexOf(sign);
                list.Add(index);
                while (true)
                {
                    if (index + sign.Length < tmp.Length)
                        index = tmp.IndexOf(sign, index + sign.Length);
                    else
                    {
                        break;
                    }
                    if (index == -1)
                        break;
                    list.Add(index);
                }
                for (int j = 0; j < tmp.Length; j++)
                {

                    if (list.IndexOf(j) != -1)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        int k;
                        for (k = j; k < j + sign.Length; k++)
                            Console.Write(tmp.ElementAt(k));
                        j = k - 1;
                    }
                    else
                    {
                        Console.ForegroundColor = defaultColor;
                        Console.Write(tmp.ElementAt(j));
                    }
                }
                Console.ForegroundColor = defaultColor;
                for (int k = 0; k < 16 - str.ElementAt(i).Count(); k++)
                    Console.Write(" ");
                if ((i + 1) % 4 == 0 || i == str.Count - 1)
                    Console.Write("\n");
            }
        }

        /// <summary>
        /// 文件列表
        /// </summary>
        /// <param name="commandArg">命令参数</param>
        /// <param name="args">操作参数</param>
        /// <param name="outFileName">重定向文件名</param>
        /// <param name="grepArg">Grep参数</param>
        /// <returns>是否成功</returns>
        public static bool Ls(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "l") //对附加参数-l的判断
            {
                Console.WriteLine("附加参数" + "-" + commandArg + "错误!");
                return false;
            }
            String absolutePath = "";
            if (args.Count > 1) //对参数的判断                               
            {
                Console.WriteLine("参数个数错误!");
                return false;
            }
            absolutePath = _driver + Program.CurrentCommand.CurrentPath;
            if (Program.CurrentCommand.CurrentPath != "/")
                absolutePath = absolutePath + "/";
            if (!String.IsNullOrEmpty(outFileName))
            {
                if (!CheckFile(outFileName))
                {
                    Console.WriteLine("重定向的文件名不合法");
                    return false;
                }
                outFileName = absolutePath + outFileName;
            }
            if (args.Count == 1) //若给出了地址，则加入此地址
            {
                if (args[0].ElementAt(0) != '/')
                    absolutePath = absolutePath + args.ElementAt(0) + '/';
                else
                {
                    absolutePath = _driver + args.ElementAt(0) + '/';   //若以“/”开头则代表从根目录开始
                }
            }
            if (!Directory.Exists(absolutePath)) //判断目录是否存在
            {
                Console.WriteLine("目录不存在!");
                return false;
            }
            DirectoryInfo di = new DirectoryInfo(absolutePath);
            List<String> output = new List<string>();
            List<String> files = new List<string>();
            List<String> dis = new List<string>();
            //用来标记目录起始位置
            int sign = 0;
            foreach (FileInfo nextFile in di.GetFiles().Where(nextFile => !IsHiddenFile(nextFile)))
            {
                if (String.IsNullOrEmpty(commandArg))
                    files.Add(nextFile.Name);
                else
                {
                    String str = "";
                    str = String.Format("{0,-16}{1,-16}{2,-16}{3,-16}", nextFile.Name,   //按格式输出
                                        (nextFile.Length / 1024 + 1).ToString("N0"),
                                        nextFile.LastWriteTime.ToString("yyyy/MM/dd"), " ");
                    files.Add(str);
                }
                sign++;
            }
            foreach (DirectoryInfo nextDirectory in
                di.GetDirectories().Where(nextDirectory => !IsHiddenDir(nextDirectory)))
            {
                if (String.IsNullOrEmpty(commandArg))   //若命令为空，就将目录名放入数组
                    dis.Add(nextDirectory.Name);
                else
                {
                    String str = "";
                    str = String.Format("{0,-16}{1,-16}{2,-16}{3,-16}", nextDirectory.Name, //按格式放入字符串
                                        (GetDirectorySize(nextDirectory) / 1024 + 1).ToString("N0"),
                                        nextDirectory.LastWriteTime.ToString("yyyy/MM/dd"), "<DIR>");
                    dis.Add(str);
                }
            }
            files = SortbyDic(files);
            dis = SortbyDic(dis);
            output.AddRange(files);
            output.AddRange(dis);
            if (grepArg.Count > 0) //管道操作
            {
                output = Grep(grepArg, output);
            }
            //带参输出
            ConsoleColor defaultColor = Console.ForegroundColor;
            if (outFileName == null)
            {
                if (!String.IsNullOrEmpty(commandArg))
                {
                    String str = "";
                    str = String.Format("{0,-16}{1,-16}{2,-16}{3,-16}", "Name", "Size<KB>", "Last modified", "Type"); //信息栏
                    Console.Write(str + "\n");
                    if (grepArg.Count != 0)
                    {
                        Out(grepArg.ElementAt(grepArg.Count - 1), output);  //高亮输出
                        return true;
                    }
                    int t = 0;
                    foreach (string s in output)
                    {
                        if (sign <= t)  //sign<=t则到了目录
                        {
                            Console.ForegroundColor = ConsoleColor.Blue;
                        }
                        Console.Write(s.Substring(0, 16));
                        Console.ForegroundColor = defaultColor;
                        Console.Write(s.Substring(16) + "\n");
                        t++;
                    }
                }
                //不带参输出
                else
                {
                    int t = 0;
                    Console.ForegroundColor = defaultColor;
                    foreach (string s in output)
                    {
                        if (grepArg.Count != 0)
                        {
                            Out1(grepArg.ElementAt(grepArg.Count - 1), output);   //高亮输出
                            return true;
                        }
                        if (t == sign)     //此时到了目录
                        {
                            Console.ForegroundColor = ConsoleColor.Blue;
                        }
                        Console.Write(String.Format("{0,-16}", s));
                        t++;
                        if (t % 4 == 0 || t == output.Count)    //保证每行4个
                        {
                            Console.Write("\n");
                        }
                    }
                    Console.ForegroundColor = defaultColor;
                }

            }
            else //重定位
            {
                Relocation(output, outFileName);
            }
            return true;
        }

        /// <summary>
        /// 复制
        /// </summary>
        /// <param name="commandArg">可带参数</param>
        /// <param name="args">参数</param>
        /// <param name="outFileName">重定位，此处应为空</param>
        /// <param name="grepArg">管道，此处应为空</param>
        /// <returns></returns>
        public static bool Cp(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "r") //对附加参数-r的判断
            {
                Console.WriteLine("附加参数" + "-" + commandArg + "错误!");
                return false;
            }
            if (!String.IsNullOrEmpty(outFileName) || grepArg.Count != 0)
            {
                Console.WriteLine("参数错误");
                return false;
            }
            String sour = "";
            String desti = "";
            int sType = 0;
            int dType = 0;
            if (args.Count != 2) //对参数的判断                               
            {
                Console.WriteLine("源地址或目的地址错误!");
                return false;
            }
            sour = _driver + Program.CurrentCommand.CurrentPath;
            if (Program.CurrentCommand.CurrentPath != "/")
                sour = sour + "/";
            desti = sour.Clone().ToString();
            if (args[0].ElementAt(0) != '/')
                sour = sour + args.ElementAt(0);
            else
            {
                sour = _driver + args.ElementAt(0);
            }
            sType = Check(sour);
            if (sType == 0)   //判断源文件是否存在
            {
                Console.WriteLine("源文件不存在");
                return false;
            }
            if (args[1].ElementAt(0) != '/')
                desti = desti + args.ElementAt(1);
            else
            {
                desti = _driver + args.ElementAt(1);
            }
            dType = Check(desti);
            if (sType == 2 && commandArg == null)  //判断是否非法复制目录
            {
                Console.WriteLine("没有附加参数不能复制目录");
                return false;
            }
            if (dType == 1 && sType == 2)  //不能复制目录到文件
            {
                Console.WriteLine("不能复制目录到文件!");
                return false;
            }
            if (sType == 1 && dType == 2) // 从文件到目录
            {
                CpfTod(sour, desti, null, 0);
            }
            if (sType == 1 && dType != 2) // 从文件到文件
            {
                CpfTof(sour, desti, 0);
            }
            if (sType == 2 && dType == 2) // 从目录到目录
            {
                if (desti.IndexOf(sour) != -1)
                {
                    Console.WriteLine("不能将一个目录放至他的子目录里！");
                    return false;
                }
                CpdTod(sour, desti, 0);
            }
            return true;
        }

        /// <summary>
        /// 移动文件或者目录
        /// </summary>
        /// <param name="commandArg">带-r可移动目录，否则只能移动文件</param>
        /// <param name="args">源地址和目的地址</param>
        /// <param name="outFileName">重定位的文件，此处应为空</param>
        /// <param name="grepArg">通道，此处应为空</param>
        /// <returns></returns>
        public static bool Mv(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "r") //对附加参数-r的判断
            {
                Console.WriteLine("附加参数" + "-" + commandArg + "错误!");
                return false;
            }
            if (!String.IsNullOrEmpty(outFileName) || grepArg.Count != 0)
            {
                Console.WriteLine("参数错误");
                return false;
            }
            String sour = "";
            String desti = "";
            int sType = 0;
            int dType = 0;
            if (args.Count != 2) //对参数的判断                               
            {
                Console.WriteLine("源地址或目的地址错误!");
                return false;
            }
            sour = _driver + Program.CurrentCommand.CurrentPath;
            if (Program.CurrentCommand.CurrentPath != "/")
                sour = sour + "/";
            desti = sour.Clone().ToString();
            if (args[0].ElementAt(0) != '/')
                sour = sour + args.ElementAt(0);
            else
            {
                sour = _driver + args.ElementAt(0);
            }
            sType = Check(sour);
            if (sType == 0)   //判断源文件是否存在
            {
                Console.WriteLine("源文件不存在");
                return false;
            }
            if (args[1].ElementAt(0) != '/')
                desti = desti + args.ElementAt(1);
            else
            {
                desti = _driver + args.ElementAt(1);
            }
            dType = Check(desti);
            if (sType == 2 && String.IsNullOrEmpty(commandArg))  //判断是否非法复制目录
            {
                Console.WriteLine("没有附加参数不能移动目录");
                return false;
            }
            if (dType == 1 && sType == 2)  //不能复制目录到文件
            {
                Console.WriteLine("不能移动目录到文件!");
                return false;
            }
            if (sType == 1 && dType == 2) // 从文件到目录
            {
                if (CpfTod(sour, desti, null, 1))
                {
                    File.Delete(sour);
                }
            }
            if (sType == 1 && dType != 2) // 从文件到文件
            {
                if (CpfTof(sour, desti, 1))
                {
                    File.Delete(sour);
                }
            }
            if (sType == 2 && dType == 2) // 从目录到目录
            {
                if (desti.IndexOf(sour) != -1)
                {
                    Console.WriteLine("不能将一个目录放至他的子目录里！");
                    return false;
                }
                DirectoryInfo di = new DirectoryInfo(sour);
                if (di.Parent != null)
                    if (di.Parent.FullName.Replace("\\", "/") == desti)
                    {
                        Console.WriteLine("目的目录地址和源目录地址相同！");
                        return false;
                    }

                if (CpdTod(sour, desti, 1))
                {
                    Delete(sour);
                }
            }

            return true;
        }

        /// <summary>
        /// 新建目录
        /// </summary>
        /// <param name="commandArg">带上可以生成路径上不存在的目录，否则报错</param>
        /// <param name="args">目录的地址</param>
        /// <param name="outFileName">重定位的文件，此处应为空</param>
        /// <param name="grepArg">管道，此处应为空</param>
        /// <returns></returns>
        public static bool MkDir(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "p") //对附加参数-p的判断
            {
                Console.WriteLine("附加参数" + "-" + commandArg + "错误!");
                return false;
            }
            if (!String.IsNullOrEmpty(outFileName) || grepArg.Count > 0) //重定向文件不为空
            {
                Console.WriteLine("参数错误");
                return false;
            }
            String absolutePath = "";
            if (args.Count != 1) //对参数的判断                               
            {
                Console.WriteLine("路径参数个数错误!");
                return false;
            }
            absolutePath = _driver + Program.CurrentCommand.CurrentPath;
            if (Program.CurrentCommand.CurrentPath != "/")
            {
                absolutePath = absolutePath + "/";
            }
            if (args[0] == "/" || args[0] == "\\" || args[0] == "//") //判断参数中是否存在非法字符
            {
                Console.WriteLine("文件夹名非法!");
                return false;
            }
            absolutePath = absolutePath + args.ElementAt(0) + '/';
            if (Directory.Exists(absolutePath) || File.Exists(absolutePath)) //如果存在此文件和文件夹
            {
                Console.WriteLine("目录或文件已经存在!");
                return false;
            }
            //找到第一个不存在的文件目录
            String str = "";
            int index = 0;
            int lastIndex = 0;
            while (true)
            {
                lastIndex = index + 1;  //上一次‘/’的位置
                index = absolutePath.IndexOf('/', index + 1);  //下一次‘/’的位置
                str = absolutePath.Substring(0, index + 1);  //从开始到index之间的字符串
                if (!Directory.Exists(str))
                    break;
            }
            if (str == absolutePath)  //如果路径存在
            {
                DirectoryInfo di = new DirectoryInfo(absolutePath);
                if (CheckFile(di.Name))
                    Directory.CreateDirectory(absolutePath);
                else
                {
                    Console.WriteLine("文件夹名非法!");
                    return false;
                }
            }
            else  //路径不存在
            {
                if (String.IsNullOrEmpty(commandArg))  //没带参数
                {
                    Console.WriteLine("文件夹" + absolutePath.Substring(lastIndex, index - lastIndex) + "不存在");
                }
                else  //有参数就从不存在的目录开始输出
                {
                    MakeDir(absolutePath, lastIndex);
                }
            }
            return true;
        }

        /// <summary>
        /// 进入目录
        /// </summary>
        /// <param name="commandArg"></param>
        /// <param name="args">目的地址</param>
        /// <param name="outFileName">重定位的文件，此处应为空</param>
        /// <param name="grepArg">通道，此处应为空</param>
        /// <returns></returns>
        public static bool Cd(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) || !String.IsNullOrEmpty(outFileName) || grepArg.Count != 0 || args.Count > 1)
            {
                Console.WriteLine("参数错误!");
                return false;
            }
            String absolutePath = "";
            absolutePath = _driver + Program.CurrentCommand.CurrentPath;
            if (args.Count == 0)  //没有参数
            {
                Program.CurrentCommand.CurrentPath = "/";
                return true;
            }
            if (args.ElementAt(0) == "/") //参数为‘/’
            {
                Program.CurrentCommand.CurrentPath = "/";
                return true;
            }
            if (Program.CurrentCommand.CurrentPath != "/")
                absolutePath = absolutePath + "/";
            absolutePath = absolutePath + args.ElementAt(0);
            if (args.ElementAt(0).ElementAt(0) == '/')
            {
                absolutePath = _driver + args.ElementAt(0);
            }
            if (Directory.Exists(absolutePath))
            {
                DirectoryInfo di = new DirectoryInfo(absolutePath);  //得出执行cd命令后的绝对地址
                absolutePath = di.FullName.Replace('\\', '/');  
                if (_driver.IndexOf(absolutePath) != -1)  //如果为指定根目录的父目录
                {
                    Program.CurrentCommand.CurrentPath = "/";
                    return true;
                }
                Program.CurrentCommand.CurrentPath =
                    absolutePath.Substring(absolutePath.IndexOf(_driver) + _driver.Length);  //当前目录
                if (Program.CurrentCommand.CurrentPath.ElementAt(Program.CurrentCommand.CurrentPath.Count() - 1) == '/' && Program.CurrentCommand.CurrentPath != "/") //如果以‘/’结尾就去掉
                    Program.CurrentCommand.CurrentPath = Program.CurrentCommand.CurrentPath.Remove(Program.CurrentCommand.CurrentPath.Count() - 1, 1);
                return true;
            }
            Console.WriteLine("路径不存在");
            return false;
        }
        /// <summary>
        /// 删除文件或者目录
        /// </summary>
        /// <param name="commandArg">带上参数可以删除目录，否则只能删除文件</param>
        /// <param name="args">删除的地址</param>
        /// <param name="outFileName">重定位，此处应为空</param>
        /// <param name="grepArg">管道，此处应为空</param>
        /// <returns></returns>
        public static bool Rm(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "r") //对附加参数-r的判断
            {
                Console.WriteLine("附加参数" + "-" + commandArg + "错误!");
                return false;
            }
            if (!String.IsNullOrEmpty(outFileName) || grepArg.Count > 0)
            {
                Console.WriteLine("参数错误");
                return false;
            }
            String absolutePath = "";
            if (args.Count != 1) //对参数的判断                               
            {
                Console.WriteLine("参数个数错误!");
                return false;
            }

            absolutePath = _driver + Program.CurrentCommand.CurrentPath; //当前绝对目录
            if (Program.CurrentCommand.CurrentPath != "/")
                absolutePath = absolutePath + "/";
            if (args[0].ElementAt(0) != '/')
                absolutePath = absolutePath + args.ElementAt(0);
            else
            {
                absolutePath = _driver + args.ElementAt(0);
            }
            if (!Directory.Exists(absolutePath) && !File.Exists(absolutePath))  //判断目录是否存在
            {
                Console.WriteLine("目录或文件不存在!");
                return false;
            }
            if (commandArg == null && Directory.Exists(absolutePath))  //无附加参数且路径为目录
            {
                Console.WriteLine("没有附加参数无法删除目录");
                return false;
            }
            if (File.Exists(absolutePath))  //如果为文件
            {
                File.Delete(absolutePath);
            }
            if (Directory.Exists(absolutePath))  //如果为目录
            {
                Delete(absolutePath);

            }
            return true;
        }

        /// <summary>
        /// 显示文件中的内容
        /// </summary>
        /// <param name="commandArg">带上显示行号，否则不显示</param>
        /// <param name="args">目的文件地址</param>
        /// <param name="outFileName">重定向</param>
        /// <param name="grepArg">管道</param>
        /// <returns></returns>
        public static bool Cat(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (args.Count > 1)
            {
                Console.WriteLine("参数错误!");
                return false;
            }
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "n")
            {
                Console.WriteLine("附加参数-" + commandArg + "错误");
                return false;
            }

            String absolutePath = "";
            absolutePath = _driver + Program.CurrentCommand.CurrentPath;
            if (Program.CurrentCommand.CurrentPath != "/")
                absolutePath = absolutePath + "/";
            if (!String.IsNullOrEmpty(outFileName))  //重定向文件不为空
            {
                if (!CheckFile(outFileName))
                {
                    Console.WriteLine("重定向的文件名不合法");
                    return false;
                }
                outFileName = absolutePath + outFileName;
            }
            if (args[0].ElementAt(0) != '/')
                absolutePath = absolutePath + args.ElementAt(0);
            else
            {
                absolutePath = _driver + args.ElementAt(0); //绝对地址
            }
            if (!File.Exists(absolutePath))
            {
                Console.WriteLine("此文件不存在!");
                return false;
            }
            List<String> output = new List<String>();
            List<String> tmp = new List<String>();
            if (String.IsNullOrEmpty(commandArg))
            {
                output = Read(absolutePath);  //从文件中读入数据
            }
            else
            {
                tmp = Read(absolutePath);
                for (int i = 0; i < tmp.Count; i++)
                {
                    output.Add(String.Format("{0,4}:  {1}", (i + 1).ToString("x").PadLeft(4, '0'), tmp.ElementAt(i)));
                    //将字符串格式化放入数组输出
                }
            }

            if (grepArg.Count > 0) //管道操作
            {
                output = Grep(grepArg, output);
                if (String.IsNullOrEmpty(outFileName))
                {
                    Out(grepArg.ElementAt(grepArg.Count - 1), output);
                    return true;
                }
            }
            if (!String.IsNullOrEmpty(outFileName))  //存在重定向文件
            {
                Write(outFileName, output);
            }
            else
                foreach (string s in output)
                {
                    Console.WriteLine(s);
                }
            return true;
        }

        /// <summary>
        /// 查找文件
        /// </summary>
        /// <param name="commandArg">带上次参数就查找具体的文件，否则查找文件夹中所有的文件</param>
        /// <param name="args">文件夹的路径</param>
        /// <param name="outFileName">重定向</param>
        /// <param name="grepArg">管道</param>
        /// <returns></returns>
        public static bool Find(String commandArg, List<String> args, String outFileName, List<String> grepArg)
        {
            //TODO
            if (!String.IsNullOrEmpty(commandArg) && commandArg != "name") //对附加参数-name的判断
            {
                Console.WriteLine("附加参数" + "-" + commandArg + "错误!");
                return false;
            }
            String absolutePath = "";
            if (args.Count > 2 || commandArg != null && args.Count < 2 || commandArg == null && args.Count >= 2)
            //对参数的判断                               
            {
                Console.WriteLine("参数个数错误!");
                return false;
            }
            absolutePath = _driver + Program.CurrentCommand.CurrentPath;
            if (Program.CurrentCommand.CurrentPath != "/")
            {
                absolutePath = absolutePath + "/";
            }
            if (args.Count != 0) //不存在参数地址
            {
                if (args[0].ElementAt(0) != '/')
                    absolutePath = absolutePath + args.ElementAt(0) + '/';
                else
                {
                    absolutePath = _driver + args.ElementAt(0) + '/';
                }
            }
            if (!Directory.Exists(absolutePath))  
            {
                Console.WriteLine("查找的目录不存在!");
                return false;
            }
            List<String> output = new List<string>();
            if (commandArg != null)
            {
                if (!CheckFile(args.ElementAt(args.Count - 1)))     //检查文件名是否合法
                {
                    Console.WriteLine("文件名" + args.ElementAt(args.Count - 1) + "不合法");
                    return false;
                }
                FindFile(absolutePath, args.ElementAt(args.Count - 1), output, args[0]+"/");
            }
            else
            {
                output.Add(args[0]);  //第一行的数据
                FindFile(absolutePath, null, output, args[0]+"/");
            }

            if (grepArg.Count > 0)
            {
                output = Grep(grepArg, output);
                if (String.IsNullOrEmpty(outFileName))
                {
                    Out(grepArg.ElementAt(grepArg.Count - 1), output); //高亮输出
                    return true;
                }
            }
            if (!String.IsNullOrEmpty(outFileName))
            {
                if (!CheckFile(outFileName))
                {
                    Console.Write("重定向的文件名不合法");
                    return false;
                }
                Relocation(output, _driver + Program.CurrentCommand.CurrentPath+"/");
            }
            else
            {
                if (args.Count >= 2 || args.Count == 1 && !String.IsNullOrEmpty(commandArg))  //如果有附加参数
                {
                    Out(args.ElementAt(args.Count - 1), output);
                    return true;
                }
                foreach (string s in output)
                {
                    Console.WriteLine(s);  //普通输出
                }
                return true;
            }
            return true;
        }
    }
    }
